Skip to content

Add corgea mcp install for agent MCP configs - #163

Merged
Ibrahimrahhal merged 8 commits into
mainfrom
cursor/mcp-install-c919
Sep 3, 2026
Merged

Add corgea mcp install for agent MCP configs#163
Ibrahimrahhal merged 8 commits into
mainfrom
cursor/mcp-install-c919

Conversation

@Ibrahimrahhal

@Ibrahimrahhal Ibrahimrahhal commented Aug 26, 2026

Copy link
Copy Markdown
Member

Adds corgea mcp install --agent <name> so a logged-in CLI can write the Corgea MCP server into an agent's JSON config using the URL and token already stored by corgea login.

Version bumped 1.12.0 → 1.13.0 (minor: new command). v1.12.0 is already tagged and on npm.

Behavior

  • Requires login, same as scan / skill / ls. An empty or missing token exits with the existing "No token set" message.
  • Writes the client-specific config each agent actually reads:
    • Cursor / Windsurf: mcp-remote with --transport http-only and the token in the header (Cursor does not interpolate ${env:NAME} from the server env block).
    • Claude Desktop (--agent claude): mcp-remote plus an env block.
    • Claude Code / VS Code: typed HTTP ("type": "http") with url + CORGEA-TOKEN header.
    • Continue: a standalone block file at .continue/mcpServers/corgea.yaml.
    • Gemini CLI / OpenCode: their native HTTP shapes.
  • Reinstalling removes the existing Corgea entry first, so the URL and token are refreshed rather than duplicated. Neighboring servers and unrelated keys are left intact.
  • --scope user (default) or project; --dir writes a custom path; --set-default persists the agent like corgea skill install.
  • Project-scope installs warn that the file now contains a token.

Review feedback addressed

Loose URL matching deleted unrelated servers. The sweep was a substring test for corgea. + /mcp, so it removed servers on notcorgea.app, evil-corgea.attacker.test, and paths that merely mentioned corgea. It now parses the URL and compares the host: Corgea's own SaaS hosts (corgea.app / *.corgea.app), or the host this run is installing, which is what recognizes a self-hosted instance on an unrelated domain.

Continue got a context provider instead of an MCP server. We wrote a contextProviders entry into config.json, which Continue does not read as MCP — the install claimed success and registered nothing. It now writes a real block file at .continue/mcpServers/corgea.yaml (Continue scans that directory in both the global dir and the workspace) with the required name/version/schema preamble and an mcpServers list. Per Continue's own config schema, an HTTP server carries headers under requestOptions, and unknown top-level keys are stripped — so a top-level headers map would have been silently discarded. Note Corgea's published MCP docs show the contextProviders form for Continue and need the same correction.

.retain() nit. remove_corgea_from_map now uses Map::retain instead of collecting keys and removing them in a loop.

Two findings are left as product decisions rather than code changes: the project-scope token in repo files, and the unpinned npx -y mcp-remote (which is what Corgea's MCP docs prescribe, and Cursor requires the bridge because its built-in url transport opens an SSE stream this server does not support).

Tests

  • 23 unit tests: host-scoped URL matching (lookalike hosts, path coincidences, self-hosted rename), Continue block shape and reinstall, path resolution, JSON merge/replace, malformed files, per-client shapes.
  • 8 integration tests driving the real binary: unauthenticated refusal, unknown agent, Cursor install from CORGEA_URL/CORGEA_TOKEN, reinstall refresh, --agent claude, --agent continue block file, and lookalike-host survival.
  • ./harness check green: clippy -D warnings, format, 807 tests.
Open in Web Open in Cursor 

Install (or reinstall) the Corgea MCP server into an agent's JSON config
using the URL and token already stored by `corgea login`. Re-running
removes any existing Corgea entry first so the endpoint and token stay
current. Unauthenticated runs fail through the same login gate as other
commands.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
@Ibrahimrahhal
Ibrahimrahhal marked this pull request as ready for review August 26, 2026 11:36
cursoragent and others added 3 commits August 26, 2026 11:40
CI under cargo-llvm-cov failed save_images_separates_references_differing_only_in_case
with "Text file busy" when execing a stub script that had just been written
in place. Write the stub via fsync+rename, wait until it is executable, and
give each test a unique temp dir.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
New `corgea mcp install` command is a minor SemVer bump. Cargo.toml is
the release source of truth; keep Cargo.lock in sync.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
Comment thread src/mcp.rs
Comment thread src/mcp.rs
Comment thread src/mcp.rs Outdated
Comment thread src/mcp.rs Outdated

@corgea-security corgea-security left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review risk: 4/5.

The installer risks credential disclosure, executes an unpinned package, can delete unrelated MCP entries, and generates an invalid Continue configuration.

Critical or high-priority changes must be addressed.

Automatic approval was not submitted: checks failed: rust-tests.

@corgea-security corgea-security added the dennis-reviewed Dennis completed an automated review label Aug 26, 2026
Bring in the merged ETXTBSY image-test fix (#164) so this PR's CI can
pass without any further MCP-branch changes.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
Comment thread src/mcp.rs Outdated
Comment thread src/mcp.rs Outdated

@yhoztak yhoztak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

cursoragent and others added 3 commits September 3, 2026 10:45
Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
Addresses three review findings on `corgea mcp install`:

- The reinstall sweep matched any URL containing "corgea." and "/mcp", so it
  deleted unrelated servers on lookalike hosts (notcorgea.app,
  evil-corgea.attacker.test) and on paths that merely mentioned corgea. Parse
  the URL instead and compare the host: Corgea's own SaaS hosts, or the host
  this run is installing, which is what recognizes a self-hosted instance.

- Continue was given a `contextProviders` entry, which Continue does not read
  as an MCP server, so the install reported success and registered nothing.
  Write a real block file at `.continue/mcpServers/corgea.yaml` instead.
  Continue's schema keeps HTTP headers under `requestOptions` and drops
  unknown top-level keys, so a top-level `headers` map would be discarded.

- Use `Map::retain` rather than collecting keys and removing them in a loop.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
v1.12.0 is already tagged and published on npm, so the new `mcp install`
command needs the next minor.

Co-authored-by: Ibrahim Rahhal <ibrahim.rahhal3636@gmail.com>
Comment thread src/mcp.rs
@Ibrahimrahhal
Ibrahimrahhal merged commit 1b40e48 into main Sep 3, 2026
18 checks passed
@Ibrahimrahhal
Ibrahimrahhal deleted the cursor/mcp-install-c919 branch September 3, 2026 11:00

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

corgea mcp install --agent opencode --scope user writes a file OpenCode does not read on macOS or Windows. Other advertised agents look correct; prior Continue / host-matching / token-in-file / unpinned mcp-remote threads stay closed.

Open in Web View Automation 

Sent by Cursor Automation: pr-flow

Comment thread src/mcp.rs
// thing entirely and does not register an MCP server.
(Agent::Continue, Scope::User) => Ok(ctx.home.join(".continue/mcpServers/corgea.yaml")),
(Agent::Continue, Scope::Project) => Ok(ctx.cwd.join(".continue/mcpServers/corgea.yaml")),
(Agent::OpenCode, Scope::User) => Ok(ctx.config_dir.join("opencode/opencode.json")),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--agent opencode --scope user installs into a path OpenCode never reads on macOS/Windows.

dirs::config_dir() is ~/Library/Application Support on macOS and %APPDATA% on Windows, so this writes:

  • macOS: ~/Library/Application Support/opencode/opencode.json
  • Windows: %APPDATA%\\opencode\\opencode.json

OpenCode's documented global config is ~/.config/opencode/opencode.json on every platform (https://dev.opencode.ai/docs/config/). This repo already follows that for skills (skill.rs maps opencode user installs to .config/opencode/skills under $HOME). The command still prints success and exits 0, so a Mac/Windows user gets a silent no-op.

Linux happens to work only because dirs::config_dir() is already ~/.config there. resolve_known_user_and_project_paths uses /home/ada/.config as config_dir, so it cannot catch this. Add an assertion with a macOS-style config_dir (.../Library/Application Support) that expects $HOME/.config/opencode/opencode.json.

Suggested change
(Agent::OpenCode, Scope::User) => Ok(ctx.config_dir.join("opencode/opencode.json")),
(Agent::OpenCode, Scope::User) => Ok(ctx.home.join(".config/opencode/opencode.json")),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dennis-reviewed Dennis completed an automated review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants